package org.jeecg.modules.car.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SsoUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.entity.basedata.BaseFloor;
import org.jeecg.entity.basedata.BaseProject;
import org.jeecg.entity.basedata.BaseRoom;
import org.jeecg.entity.car.CarInfo;
import org.jeecg.entity.car.CarPort;
import org.jeecg.entity.charge.ChargeFeeitem;
import org.jeecg.modules.car.entity.CarParkInfo;
import org.jeecg.modules.car.service.*;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

 /**
 * @Description: 车位管理
 * @Author: jeecg-boot
 * @Date:   2020-08-26
 * @Version: V1.0
 */
@Slf4j
@Api(tags="车位管理")
@RestController
@RequestMapping("/b/car/carPort")
public class CarPortController {
	 @Autowired
	 private ICarPortService carPortService;
	 @Autowired
	 private ICarParkInfoService carParkInfoService;
	 @Autowired
	 private ICarInfoService carInfoService;
	 @Autowired
	 private IBaseRoomService baseRoomService;
	 @Autowired
	 private ISysUserRoleService sysUserRoleService;
	 @Autowired
	 private IChargeFeeItemService chargeFeeItemService;

	/**
	  * 分页列表查询
	 * @param carPort
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "车位管理-分页列表查询")
	@ApiOperation(value="车位管理-分页列表查询", notes="车位管理-分页列表查询")
	@GetMapping(value = "/list")
	public Result<IPage<CarPort>> queryPageList(CarPort carPort,
												@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
												@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
												HttpServletRequest req) {
		Result<IPage<CarPort>> result = new Result<IPage<CarPort>>();
		carPort.setSqlMap(sysUserRoleService.dataScopeProjectOnlyFilter(SsoUtil.getLoginUser(),"p",carPort.getMenuPath(),null,null));
		Page<CarPort> page = new Page<CarPort>(pageNo, pageSize);
		page.setRecords(carPortService.findPage(page,carPort));
		result.setSuccess(true);
		result.setResult(page);
		return result;
	}

	 @AutoLog(value = "车位-通过车场id查询")
	 @ApiOperation(value="车位-通过车场id查询", notes="车位-通过车场id查询")
	 @PostMapping(value = "/queryCarPort")
	 public Result<List<CarPort>> queryCarPort(@RequestParam(name="parkId",required=true) String parkId) {
		 List<CarPort> carPorts = carPortService.findByParkId(parkId);
		 if(carPorts==null || carPorts.size() <= 0) {
			 return Result.error("未找到对应实体");
		 }else {
			 return Result.ok(carPorts);
		 }
	 }

	 @AutoLog(value = "车位-通过车场id查询车场id名称")
	 @ApiOperation(value="车位-通过车场id查询车场id名称", notes="车位-通过车场id查询车场id名称")
	 @PostMapping(value = "/queryCarPortName")
	 public Result<List<CarPort>> queryCarPortName(@RequestParam(name="parkId",required=true) String parkId) {
		 List<CarPort> carPorts = carPortService.queryCarPortName(parkId);
		 if(carPorts==null || carPorts.size() <= 0) {
			 return Result.error("未找到对应实体");
		 }else {
			 return Result.ok(carPorts);
		 }
	 }

	/**
	  *   添加
	 * @param carPort
	 * @return
	 */
	@AutoLog(value = "车位管理-添加")
	@ApiOperation(value="车位管理-添加", notes="车位管理-添加")
	@PostMapping(value = "/add")
	public Result<CarPort> add(@RequestBody CarPort carPort) {
		Result<CarPort> result = new Result<CarPort>();
		try {
            CarPort existPort =  carPortService.getByParkIdAndPortNum(carPort.getParkId(),carPort.getCarportNum());
            if (existPort != null){
                return result.error500("填写的车位号在系统已存在，请勿重复添加");
            }
			if (null == carPort.getChargeStartTime()){
				return result.error500("初始计费日期不能为空！");
			}
			//当天日期
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date date = sdf.parse(DateUtils.date2Str(new Date(),DateUtils.date_sdf));
			//入住时间不为空
			if (null != carPort.getCheckInTime()){
			    if (carPort.getChargeStartTime().getTime() < carPort.getCheckInTime().getTime()){
			        return result.error500("开始计费日期不能小于入户日期");
                }
				//车位有效期开始 = 入住日期
				carPort.setLocalStartTime(carPort.getCheckInTime());
				//到期日 = 初始计费日期
				Calendar ca = Calendar.getInstance();
				ca.setTime(carPort.getChargeStartTime());
				ca.add(Calendar.SECOND, -1);//减去1秒获取前一天
				carPort.setLocalEndTime(ca.getTime());
			}else {
				//初始计费日期   > 当前时间
				if (carPort.getChargeStartTime().getTime() > date.getTime()){
					//起始日期 = 现在
					carPort.setLocalStartTime(date);
					//到期日 = 初始计费日期
					Calendar ca = Calendar.getInstance();
					ca.setTime(carPort.getChargeStartTime());
					ca.add(Calendar.SECOND, -1);//减去1秒获取前一天
					carPort.setLocalEndTime(ca.getTime());
				}
			}
			carPortService.save(carPort);
			result.success("添加成功！");
		} catch (Exception e) {
			log.error(e.getMessage(),e);
			result.error500("操作失败");
		}
		return result;
	}
	
	/**
	  *  编辑
	 * @param carPort
	 * @return
	 */
	@AutoLog(value = "车位管理-编辑")
	@ApiOperation(value="车位管理-编辑", notes="车位管理-编辑")
	@PutMapping(value = "/edit")
	public Result<CarPort> edit(@RequestBody CarPort carPort) {
		Result<CarPort> result = new Result<CarPort>();
		CarPort carPortEntity = carPortService.getById(carPort.getId());
		if(carPortEntity==null) {
			result.error500("未找到对应实体");
		}else {
			List<CarInfo> infos = carInfoService.getByCarPortId(carPort.getId());
			//修改绑定车辆房间信息
			if (infos.size() > 0){
				for (CarInfo carInfo : infos){
					carInfo.setFloorId(carPort.getFloorId());
					carInfo.setFloorName(carPort.getFloorName());
					carInfo.setRoomId(carPort.getRoomId());
					carInfo.setRoomName(carPort.getRoomName());
					carInfoService.updateById(carInfo);
				}
			}
			boolean ok = carPortService.updateById(carPort);
			if(ok) {
				result.success("修改成功!");
			}
		}
		return result;
	}
	
	/**
	  *   通过id删除
	 * @param id
	 * @return
	 */
	@AutoLog(value = "车位管理-通过id删除")
	@ApiOperation(value="车位管理-通过id删除", notes="车位管理-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		try {
//			CarInfo carInfo = carInfoService.getByCarPortId(id);
			int count = carInfoService.count(Wrappers.<CarInfo>query().lambda().eq(CarInfo::getCarPortId,id));
			if (count > 0){
				return Result.error("当前车位已经绑定车辆无法删除");
			}
			carPortService.removeById(id);
		} catch (Exception e) {
			log.error("删除失败",e.getMessage());
			return Result.error("删除失败!");
		}
		return Result.ok("删除成功!");
	}
	
	/**
	  *  批量删除
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "车位管理-批量删除")
	@ApiOperation(value="车位管理-批量删除", notes="车位管理-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<CarPort> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		Result<CarPort> result = new Result<CarPort>();
		if(ids==null || "".equals(ids.trim())) {
			result.error500("参数不识别！");
		}else {
			this.carPortService.removeByIds(Arrays.asList(ids.split(",")));
			result.success("删除成功!");
		}
		return result;
	}
	
	/**
	  * 通过id查询
	 * @param id
	 * @return
	 */
	@AutoLog(value = "车位管理-通过id查询")
	@ApiOperation(value="车位管理-通过id查询", notes="车位管理-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<CarPort> queryById(@RequestParam(name="id",required=true) String id) {
		Result<CarPort> result = new Result<CarPort>();
		CarPort carPort = carPortService.getById(id);
		if(carPort==null) {
			result.error500("未找到对应实体");
		}else {
			result.setResult(carPort);
			result.setSuccess(true);
		}
		return result;
	}

  /**
      * 导出excel
   *
   * @param request
   * @param response
   */
  @RequestMapping(value = "/exportXls")
  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
      // Step.1 组装查询条件
      QueryWrapper<CarPort> queryWrapper = null;
      try {
          String paramsStr = request.getParameter("paramsStr");
          if (oConvertUtils.isNotEmpty(paramsStr)) {
              String deString = URLDecoder.decode(paramsStr, "UTF-8");
              CarPort carPort = JSON.parseObject(deString, CarPort.class);
              queryWrapper = QueryGenerator.initQueryWrapper(carPort, request.getParameterMap());
          }
      } catch (UnsupportedEncodingException e) {
          e.printStackTrace();
      }
	  LoginUser loginUser =  SsoUtil.getLoginUser();
      //Step.2 AutoPoi 导出Excel
      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
      List<CarPort> pageList = carPortService.list(queryWrapper);
      //导出文件名称
      mv.addObject(NormalExcelConstants.FILE_NAME, "车位管理列表");
      mv.addObject(NormalExcelConstants.CLASS, CarPort.class);
      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("车位管理列表数据", "导出人:" + loginUser.getRealname(), "导出信息"));
      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
      return mv;
  }

  /**
      * 通过excel导入数据
   *
   * @param request
   * @param response
   * @return
   */
  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
	  LoginUser loginUser = SsoUtil.getLoginUser();
      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
          MultipartFile file = entity.getValue();// 获取上传文件对象
          ImportParams params = new ImportParams();
          int titleRow = 0;
          params.setTitleRows(titleRow);
          params.setHeadRows(titleRow++);
          params.setNeedSave(true);
          try {
              List<CarPort> listCarPorts = ExcelImportUtil.importExcel(file.getInputStream(), CarPort.class, params);
              if (listCarPorts.size() <= 0){
              	return Result.error("文件内容为空，导入无效！");
			  }
			  int successNum = 0;
			  int failureNum = 0;
			  StringBuilder failureMsg = new StringBuilder();
			  Map<String,Integer> carPortMap = new HashMap<>(); //本次导入的
              for (CarPort carPort:listCarPorts){
              	titleRow++;
              	if (StringUtils.isBlank(carPort.getProjectName())){
					failureMsg.append("<br/>第").append(titleRow).append("行：请输入项目名称; ");
					failureNum++;
					continue;
				}
				if (StringUtils.isBlank(carPort.getParkName())){
					failureMsg.append("<br/>第").append(titleRow).append("行：请输入车场名称; ");
					failureNum++;
					continue;
				}
				if (StringUtils.isBlank(carPort.getStatusName())){
					failureMsg.append("<br/>第").append(titleRow).append("行：请选择车位状态; ");
					failureNum++;
					continue;
				}
				if (StringUtils.isBlank(carPort.getCarportNum())){
					failureMsg.append("<br/>第").append(titleRow).append("行：请输入车位号; ");
					failureNum++;
					continue;
				}
                while (carPort.getCarportNum().endsWith(".0")){
                    carPort.setCarportNum(carPort.getCarportNum().substring(0,carPort.getCarportNum().length() - 2 ));
                }
				if (null == carPort.getChargeStartTime()){
					failureMsg.append("<br/>第").append(titleRow).append("行：请输入开始计费日期; ");
					failureNum++;
					continue;
				}
				BaseProject baseProject =  carPortService.getProjectByName(carPort.getProjectName());
              	if (baseProject == null){
					failureMsg.append("<br/>第").append(titleRow).append("行：填写的项目名称系统中不存在; ");
					failureNum++;
					continue;
				}
				carPort.setProjectId(baseProject.getId());
              	carPort.setProjectName(baseProject.getName());
				CarParkInfo carParkInfo = carParkInfoService.getByProjectIdAndParkName(baseProject.getId(),carPort.getParkName());
				if (carParkInfo == null){
					failureMsg.append("<br/>第").append(titleRow).append("行：填写的车场名称系统中不存在; ");
					failureNum++;
					continue;
				}
				carPort.setParkId(carParkInfo.getId());
				carPort.setParkName(carParkInfo.getParkName());
				//判断车位号是否已经存在
				CarPort existPort =  carPortService.getByParkIdAndPortNum(carParkInfo.getId(),carPort.getCarportNum());
				if (existPort != null){
					failureMsg.append("<br/>第").append(titleRow).append("行：填写的车位号在系统已存在，请勿重复添加; ");
					failureNum++;
					continue;
				}
				Integer mapRow = carPortMap.get(carPort.getParkId() + "|" + carPort.getCarportNum());
				if (mapRow != null){
					failureMsg.append("<br/>第").append(titleRow).append("行：填写的车位号与").append(mapRow).append("行的车位号相同,请勿重复;");
					failureNum++;
					continue;
				} else {
					carPortMap.put(carPort.getParkId() + "|" + carPort.getCarportNum(),titleRow);
				}
				if (carPort.getStatusName().equals("未售")){
					carPort.setStatus(1);
				} else if(carPort.getStatusName().equals("已售")){
					carPort.setStatus(2);
				} else if (carPort.getStatusName().equals("租赁")){
					carPort.setStatus(3);
				}
				carPort.setIsAb(("是").equals(carPort.getCarPortType()) ? 1 : 0);
				if (StringUtils.isNotBlank(carPort.getFloorName()) && StringUtils.isNotBlank(carPort.getRoomName())){
					BaseFloor baseFloor = baseRoomService.getByProjectIdName(baseProject.getId(), carPort.getFloorName(),loginUser.getTenantId());
					if (baseFloor == null){
						failureMsg.append("<br/>第").append(titleRow).append("行：楼栋名称不存在;");
						failureNum++;
						continue;
					}
					BaseRoom baseRoom = baseRoomService.getByFloorIdName(baseFloor.getId(), carPort.getRoomName(), loginUser.getTenantId());
					if (baseRoom == null){
						failureMsg.append("<br/>第").append(titleRow).append("行：房间号不存在;");
						failureNum++;
						continue;
					}
					carPort.setFloorId(baseFloor.getId());
					carPort.setRoomId(baseRoom.getId());
				}
              //当天日期
              SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
              Date date = sdf.parse(DateUtils.date2Str(new Date(),DateUtils.date_sdf));
              //入住时间不为空
              if (null != carPort.getCheckInTime()){
                  if (carPort.getChargeStartTime().getTime() < carPort.getCheckInTime().getTime()){
                      failureMsg.append("<br/>第").append(titleRow).append("行：开始计费日期不能小于入户日期;");
                      failureNum++;
                      continue;
                  }
                  //车位有效期开始 = 入住日期
                  carPort.setLocalStartTime(carPort.getCheckInTime());
                  //到期日 = 初始计费日期
				  Calendar ca = Calendar.getInstance();
				  ca.setTime(carPort.getChargeStartTime());
				  ca.add(Calendar.SECOND, -1);//减去1秒获取前一天
				  carPort.setLocalEndTime(ca.getTime());
                 // carPort.setLocalEndTime(carPort.getChargeStartTime());
              }else {
                  //初始计费日期   > 当前时间
                  if (carPort.getChargeStartTime().getTime() > date.getTime()){
                      //起始日期 = 现在
                      carPort.setLocalStartTime(date);
                      //到期日 = 初始计费日期
					  Calendar ca = Calendar.getInstance();
					  ca.setTime(carPort.getChargeStartTime());
					  ca.add(Calendar.SECOND, -1);//减去1秒获取前一天
					  carPort.setLocalEndTime(ca.getTime());
                     // carPort.setLocalEndTime(carPort.getChargeStartTime());
                  }
              }
              if (StringUtils.isBlank(carPort.getItemName())){
				  failureMsg.append("<br/>第").append(titleRow).append("行：收费项目名称不能为空;");
				  failureNum++;
				  continue;
			  }
			  if (StringUtils.isBlank(carPort.getUnitAccountName())){
				  failureMsg.append("<br/>第").append(titleRow).append("行：计费精度不能为空;");
				  failureNum++;
				  continue;
			  }
			  if (carPort.getUnitAccountName().equals("元")){
				  carPort.setUnitAccount(0);
			  } else if(carPort.getUnitAccountName().equals("角")){
				  carPort.setUnitAccount(1);
			  } else if (carPort.getUnitAccountName().equals("分")){
				  carPort.setUnitAccount(2);
			  }
			  if (null == carPort.getPrice()){
				  failureMsg.append("<br/>第").append(titleRow).append("行：收费单价不能为空;");
				  failureNum++;
				  continue;
			  }
			 List<ChargeFeeitem> chargeFeeitemList = chargeFeeItemService.getByFeeName(carPort.getItemName(),loginUser.getTenantId());
			  if (chargeFeeitemList.size() <= 0){
				  failureMsg.append("<br/>第").append(titleRow).append("行：未查询到名称为["+carPort.getItemName()+"]的收费项;");
				  failureNum++;
				  continue;
			  }
			  carPort.setItemId(chargeFeeitemList.get(0).getId());
			 }
			  if (failureNum > 0 ){
				  return Result.error("文件导入失败:" + failureMsg.toString());
			  }
              carPortService.saveBatch(listCarPorts);
              return Result.ok("文件导入成功！数据行数:" + listCarPorts.size());
          } catch (Exception e) {
              log.error(e.getMessage(),e);
              return Result.error("文件导入失败:"+e.getMessage());
          } finally {
              try {
                  file.getInputStream().close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      return Result.ok("文件导入失败！");
  }

	 /**
	  * 通过车场id查询
	  * @param \
	  * @return
	  */
	 @AutoLog(value = "车位管理-通过车场id查询")
	 @ApiOperation(value="车位管理-通过车场id查询", notes="车位管理-通过车场id查询")
	 @GetMapping(value = "/getCarPortByCarParkId")
	 public Result<List<CarPort>> getCarPortByCarParkId(@RequestParam(name="parkId",required=true) String parkId) {
		 Result<List<CarPort>> result = new Result<List<CarPort>>();
		 List<CarPort> carPort = new ArrayList<CarPort>();
		 try {
			 carPort = carPortService.getCarPortByCarParkId(parkId);
			 result.setResult(carPort);
			 result.setSuccess(true);
		 } catch (Exception e) {
			 log.error(e.getMessage(),e);
			 result.error500("操作失败");
		 }
		 return result;
	 }

}
